package com.asiainfo.complier.format;

import java.util.ArrayList;
import java.util.Stack;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class JavaCodeFormat {

	private static char startChar = '(';
	private static char endChar = ')';

	/**
	 * get muti line
	 * 
	 * @param code
	 * @return
	 */
	private static String getMutiLines(String s) {

		Pattern pattern1 = Pattern.compile("//(.*)"); // 锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷双斜锟竭匡拷头锟斤拷
		Matcher matcher1 = pattern1.matcher(s);
		s = matcher1.replaceAll(""); // 锟芥换锟斤拷一锟斤拷注锟斤拷

		Pattern pattern2 = Pattern.compile("/\\*(.*?)\\*/", Pattern.DOTALL);
		/*
		 * 锟斤拷锟斤拷锟斤拷锟斤拷/*锟斤拷始锟斤拷锟斤拷 锟斤拷尾锟斤拷 Pattern.DOTALL锟斤拷锟斤拷思锟角猴拷涂模式锟斤拷
		 * 锟斤拷锟斤拷模式锟斤拷.锟斤拷锟斤拷牛锟狡ワ拷锟斤拷锟斤拷锟斤拷址锟�
		 */
		Matcher matcher2 = pattern2.matcher(s);
		s = matcher2.replaceAll(""); // 锟芥换锟节讹拷锟斤拷注锟斤拷

		Pattern pattern3 = Pattern.compile("/\\*\\*(.*?)\\*/", Pattern.DOTALL);
		// 锟斤拷锟斤拷锟斤拷锟斤拷/**锟斤拷始锟斤拷锟斤拷*/锟斤拷尾
		Matcher matcher3 = pattern3.matcher(s);
		s = matcher3.replaceAll(""); // 锟芥换锟斤拷锟斤拷锟斤拷注锟斤拷

		return s;
	}

	private static int searchCratPair(String allText, int dot) {
		int size = allText.length();

		Stack<Character> strStack = new Stack<Character>();

		while (dot < size) {
			char curChar = allText.charAt(dot);
			if (curChar == startChar)
				strStack.push(startChar);
			else if (curChar == endChar) {
				if (!strStack.isEmpty())
					strStack.pop();
				if (strStack.isEmpty()) {
					return dot;
				}
			}
			dot++;
		}
		return -1;

	}

	public static String doFormat(String code) {
		ArrayList<CodeLine> codeInfoList = new ArrayList<CodeLine>();
		codeInfoList.clear();
		code = getMutiLines(code);
		code = code + "    ";

		int size = code.length() - 1;
		int lastPos = 0;
		int pos = 0;
		int step = 1;
		code = code.replace('\r', ' ');

		while (pos < size) {
			char c = code.charAt(pos);
			if (pos + 4 < size) {
				String strFor = code.substring(pos, pos + 4);
				if (strFor.equals("for ")) {
					pos += 3;
					int index = code.indexOf("(", pos);
					if (index != -1) {
						int tmpPos = pos;
						index = searchCratPair(code, tmpPos);
						if (index != -1) {
							boolean bIndent = false;
							String line = code.substring(lastPos, index + 1);
							line = line.replace('\n', ' ').trim();
							CodeLine info = new CodeLine(step, line);
							codeInfoList.add(info);
							pos = index;
							pos++;
							lastPos = pos;
							if (bIndent)
								step++;
						}
					}
				}
			}
			if (pos + 3 < size) {
				String strIf = code.substring(pos, pos + 3);
				if (strIf.equals("if ")) {
					pos += 2;
					int index = code.indexOf("(", pos);
					if (index != -1) {
						int tmpPos = pos;

						index = searchCratPair(code, tmpPos);

						if (index != -1) {

							String line = code.substring(lastPos, index + 1);
							line = line.replace('\n', ' ').trim();
							CodeLine info = new CodeLine(step, line);
							codeInfoList.add(info);
							pos = index;
							pos++;
							lastPos = pos;

						}
					}
				}
			}
			if (c == ';') {
				String line = code.substring(lastPos, pos + 1);
				line = line.replace('\n', ' ').trim();
				CodeLine info = new CodeLine(step, line);
				codeInfoList.add(info);
				pos++;
				lastPos = pos;
			} else if (c == '{') {
				step++;
				String line = code.substring(lastPos, pos + 1);
				line = line.replace('\n', ' ').trim();
				if (line.equals("{")) {
					int len = codeInfoList.size();
					String curline = codeInfoList.get(len - 1).getLine();
					codeInfoList.get(len - 1).setLine(curline + "{");
				} else {
					CodeLine info = new CodeLine(step, line);
					codeInfoList.add(info);
				}

				pos++;
				lastPos = pos;

			} else if (c == '}') {
				step--;
				String line = code.substring(lastPos, pos + 1);
				line = line.replace('\n', ' ').trim();
				CodeLine info = new CodeLine(step, line);
				codeInfoList.add(info);
				pos++;
				lastPos = pos;
			} else {
				pos++;
			}

		}
		String formatString = "";
		for (CodeLine info : codeInfoList) {
			formatString += info.toString();
		}
		return formatString;
	}

	private JavaCodeFormat() {
	}
}
